/**
 * 命令队列实战示例
 * 
 * 演示真实游戏场景中如何使用命令队列
 * 
 * @author AI Assistant
 * @date 2025-11-26
 */

import { ecs } from "../../../core/ecs/ECS";
import { Vec3, Color } from "cc";
import { LogicCmd, CommandPriority } from "./index";
import { ViewComponent } from "../component/ViewComponent";

// ==================== 1. 定义游戏组件 ====================

/**
 * 位置组件
 */
@ecs.register('Position')
export class PositionComponent extends ecs.Comp {
    x: number = 0;
    y: number = 0;
    
    reset(): void {
        this.x = 0;
        this.y = 0;
    }
}

/**
 * 速度组件
 */
@ecs.register('Velocity')
export class VelocityComponent extends ecs.Comp {
    x: number = 0;
    y: number = 0;
    
    reset(): void {
        this.x = 0;
        this.y = 0;
    }
}

/**
 * 生命值组件
 */
@ecs.register('Health')
export class HealthComponent extends ecs.Comp {
    current: number = 100;
    max: number = 100;
    justHit: boolean = false;
    
    reset(): void {
        this.current = 100;
        this.max = 100;
        this.justHit = false;
    }
    
    takeDamage(damage: number): void {
        this.current = Math.max(0, this.current - damage);
        this.justHit = true;
    }
    
    isAlive(): boolean {
        return this.current > 0;
    }
}

/**
 * 玩家标签组件
 */
@ecs.register('Player')
export class PlayerComponent extends ecs.Comp {
    reset(): void {}
}

/**
 * 敌人标签组件
 */
@ecs.register('Enemy')
export class EnemyComponent extends ecs.Comp {
    reset(): void {}
}

// ==================== 2. 定义实体 ====================

/**
 * 玩家实体
 */
@ecs.register('PlayerEntity')
export class PlayerEntity extends ecs.Entity {
    PositionComponent!: PositionComponent;
    VelocityComponent!: VelocityComponent;
    HealthComponent!: HealthComponent;
    PlayerComponent!: PlayerComponent;
    ViewComponent!: ViewComponent;
    
    init(): void {
        this.add(PositionComponent);
        this.add(VelocityComponent);
        this.add(HealthComponent);
        this.add(PlayerComponent);
        // ViewComponent 由 RenderSystem 创建时添加
    }
}

/**
 * 敌人实体
 */
@ecs.register('EnemyEntity')
export class EnemyEntity extends ecs.Entity {
    PositionComponent!: PositionComponent;
    VelocityComponent!: VelocityComponent;
    HealthComponent!: HealthComponent;
    EnemyComponent!: EnemyComponent;
    ViewComponent!: ViewComponent;
    
    init(): void {
        this.add(PositionComponent);
        this.add(VelocityComponent);
        this.add(HealthComponent);
        this.add(EnemyComponent);
    }
}

// ==================== 3. 定义逻辑系统 ====================

/**
 * 移动逻辑系统
 */
@ecs.register('MovementLogic')
export class MovementLogicSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
    filter(): ecs.IMatcher {
        return ecs.allOf(PositionComponent, VelocityComponent, ViewComponent);
    }
    
    update(entity: ecs.Entity): void {
        const pos = entity.get(PositionComponent)!;
        const vel = entity.get(VelocityComponent)!;
        
        // 逻辑层：计算新位置
        pos.x += vel.x * this.dt;
        pos.y += vel.y * this.dt;
        
        // 渲染层：通过命令队列更新视图
        LogicCmd.setPosition(entity.eid, pos.x, pos.y);
        
        // 根据速度播放动画
        const speed = Math.sqrt(vel.x * vel.x + vel.y * vel.y);
        if (speed > 50) {
            LogicCmd.playAnimation(entity.eid, 'run', true);
        } else if (speed > 10) {
            LogicCmd.playAnimation(entity.eid, 'walk', true);
        } else {
            LogicCmd.playAnimation(entity.eid, 'idle', true);
        }
    }
}

/**
 * 战斗逻辑系统
 */
@ecs.register('CombatLogic')
export class CombatLogicSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
    filter(): ecs.IMatcher {
        return ecs.allOf(HealthComponent, ViewComponent);
    }
    
    update(entity: ecs.Entity): void {
        const health = entity.get(HealthComponent)!;
        
        // 处理受击
        if (health.justHit) {
            // 1. 播放受击动画（高优先级）
            LogicCmd.playAnimation(
                entity.eid,
                'hit',
                false,
                CommandPriority.HIGH
            );
            
            // 2. 闪烁效果
            LogicCmd.setSpriteOpacity(entity.eid, 128, CommandPriority.HIGH);
            
            setTimeout(() => {
                LogicCmd.setSpriteOpacity(entity.eid, 255);
            }, 200);
            
            // 3. 根据生命值改变颜色
            const healthPercent = health.current / health.max;
            if (healthPercent > 0.5) {
                LogicCmd.setSpriteColor(entity.eid, new Color(255, 255, 255));
            } else if (healthPercent > 0.2) {
                LogicCmd.setSpriteColor(entity.eid, new Color(255, 200, 0)); // 黄色警告
            } else {
                LogicCmd.setSpriteColor(entity.eid, new Color(255, 0, 0)); // 红色危险
            }
            
            health.justHit = false;
        }
        
        // 处理死亡
        if (!health.isAlive()) {
            // 1. 播放死亡动画（关键优先级）
            LogicCmd.playAnimation(
                entity.eid,
                'death',
                false,
                CommandPriority.CRITICAL
            );
            
            // 2. 延迟隐藏
            setTimeout(() => {
                LogicCmd.hide(entity.eid);
            }, 1000);
            
            // 3. 延迟销毁
            setTimeout(() => {
                LogicCmd.destroyNode(entity.eid, true);
                entity.destroy();
            }, 2000);
        }
    }
}

// ==================== 4. 实战示例 ====================

/**
 * 实战示例：创建一个简单的战斗场景
 */
export class BattleSceneExample {
    private player: PlayerEntity | null = null;
    private enemies: EnemyEntity[] = [];
    
    /**
     * 初始化战斗场景
     */
    async initialize(): Promise<void> {
        console.log('初始化战斗场景...');
        
        // 注意：实际使用时需要先初始化 renderSystem
        // 以便创建实体视图
        
        // 创建玩家（示例）
        // this.player = ecs.getEntity(PlayerEntity);
        // await renderSystem.createEntityView(this.player, 'game', 'prefabs/player');
        
        // 创建敌人（示例）
        // for (let i = 0; i < 5; i++) {
        //     const enemy = ecs.getEntity(EnemyEntity);
        //     await renderSystem.createEntityView(enemy, 'game', 'prefabs/enemy');
        //     this.enemies.push(enemy);
        // }
        
        console.log('✅ 战斗场景初始化完成');
    }
    
    /**
     * 模拟玩家移动
     */
    movePlayer(direction: Vec3): void {
        if (!this.player) return;
        
        // 更新速度（逻辑数据）
        this.player.VelocityComponent.x = direction.x * 100;
        this.player.VelocityComponent.y = direction.y * 100;
        
        // 渲染命令会在 MovementLogicSystem 中自动发送
        console.log('玩家移动:', direction);
    }
    
    /**
     * 模拟攻击敌人
     */
    attackEnemy(enemyIndex: number, damage: number): void {
        if (enemyIndex < 0 || enemyIndex >= this.enemies.length) return;
        
        const enemy = this.enemies[enemyIndex];
        
        // 1. 造成伤害（逻辑数据）
        enemy.HealthComponent.takeDamage(damage);
        
        // 2. 渲染命令会在 CombatLogicSystem 中自动处理
        // （播放受击动画、闪烁效果等）
        
        console.log(`攻击敌人 ${enemyIndex}，造成 ${damage} 伤害`);
        console.log(`敌人生命值: ${enemy.HealthComponent.current}/${enemy.HealthComponent.max}`);
    }
    
    /**
     * 模拟批量操作：隐藏所有敌人
     */
    hideAllEnemies(): void {
        const enemyIds = this.enemies.map(e => e.eid);
        LogicCmd.batchSetVisible(enemyIds, false);
        
        console.log(`隐藏了 ${this.enemies.length} 个敌人`);
    }
    
    /**
     * 模拟批量操作：显示所有敌人
     */
    showAllEnemies(): void {
        const enemyIds = this.enemies.map(e => e.eid);
        LogicCmd.batchSetVisible(enemyIds, true);
        
        console.log(`显示了 ${this.enemies.length} 个敌人`);
    }
}

// ==================== 5. 性能对比示例 ====================

/**
 * 性能对比：命令队列 vs 直接操作
 */
export class PerformanceComparison {
    /**
     * 测试 1: 直接操作（不推荐）
     */
    static testDirectOperation(entities: ecs.Entity[], iterations: number): number {
        const startTime = performance.now();
        
        for (let i = 0; i < iterations; i++) {
            entities.forEach(entity => {
                const view = entity.get(ViewComponent);
                if (view && view.node) {
                    // 直接操作节点
                    view.node.setPosition(Math.random() * 100, Math.random() * 100);
                }
            });
        }
        
        const endTime = performance.now();
        return endTime - startTime;
    }
    
    /**
     * 测试 2: 使用命令队列（推荐）
     */
    static testCommandQueue(entities: ecs.Entity[], iterations: number): number {
        const startTime = performance.now();
        
        for (let i = 0; i < iterations; i++) {
            // 批量发送命令
            const positions = entities.map(e => ({
                entityId: e.eid,
                x: Math.random() * 100,
                y: Math.random() * 100
            }));
            
            LogicCmd.batchSetPosition(positions);
        }
        
        const endTime = performance.now();
        return endTime - startTime;
    }
    
    /**
     * 运行对比测试
     */
    static async runComparison(): Promise<void> {
        console.log('\n========== 性能对比测试 ==========\n');
        
        // 创建测试实体（需要先初始化）
        const entities: ecs.Entity[] = [];
        // for (let i = 0; i < 100; i++) {
        //     const entity = ecs.getEntity(ecs.Entity);
        //     entities.push(entity);
        // }
        
        const iterations = 100;
        
        // 测试 1
        console.log('测试 1: 直接操作');
        const time1 = this.testDirectOperation(entities, iterations);
        console.log(`耗时: ${time1.toFixed(2)}ms`);
        
        // 测试 2
        console.log('\n测试 2: 命令队列');
        const time2 = this.testCommandQueue(entities, iterations);
        console.log(`耗时: ${time2.toFixed(2)}ms`);
        
        // 对比
        console.log('\n========== 结果对比 ==========');
        console.log(`直接操作: ${time1.toFixed(2)}ms`);
        console.log(`命令队列: ${time2.toFixed(2)}ms`);
        console.log(`性能差异: ${((time1 - time2) / time1 * 100).toFixed(2)}%`);
        console.log('==============================\n');
    }
}

// ==================== 6. 导出便捷接口 ====================

export const PracticalExamples = {
    BattleScene: BattleSceneExample,
    PerformanceComparison
};

// 使用示例：
// const battle = new PracticalExamples.BattleScene();
// await battle.initialize();
// battle.movePlayer(new Vec3(1, 0, 0));
// battle.attackEnemy(0, 20);

